package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.domain.db.UserFreezing;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.FocusUser;
import com.itheima.domain.mongo.UserLike;
import com.itheima.domain.mongo.Video;
import com.itheima.service.db.FreezingService;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.VideoService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.DateFormatUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class VideoManager {

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    @Reference
    private VideoService videoService;

    @Reference
    private UserInfoService userInfoService;

    @Reference
    private CommentService commentService;

    @Autowired
    private MQVideoManager mqVideoManager;
    @Reference
    private FreezingService freezingService;
    //查询推荐给我的视频
    @Cacheable(value = "tanhua", key = "'video_'+#userId+':'+#pageNum+'_'+#pageSize")
    public PageBeanVo findRecommendVideo(Long userId, Integer pageNum, Integer pageSize) {

        System.out.println("从数据看查询视频........");

        //2. 调用service分页查询推荐给我的视频详情
        PageBeanVo pageBeanVo = videoService.findVideo(userId, pageNum, pageSize);

        //3. 封装返回结果
        List<Video> videoList = (List<Video>) pageBeanVo.getItems();
        List<VideoVo> videoVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(videoList)) {
            for (Video video : videoList) {
                VideoVo videoVo = new VideoVo();

                //3-1 设置视频发布人信息
                UserInfo userInfo = userInfoService.findById(video.getUserId());
                BeanUtils.copyProperties(userInfo, videoVo);

                //3-2 设置视频信息
                BeanUtils.copyProperties(video, videoVo);

                //3-3 设置上面没有赋值成功的
                videoVo.setId(video.getId().toHexString());//设置视频id
                videoVo.setCover(video.getPicUrl());//视频封面
                videoVo.setSignature(video.getText());//视频签名

                //todo 临时模拟
                videoVo.setHasLiked(1);//是否喜欢

                String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.get().getId(), video.getUserId());
                if (stringRedisTemplate.hasKey(key)) {
                    videoVo.setHasFocus(1);//关注
                } else {
                    videoVo.setHasFocus(0);//未关注
                }

                videoVoList.add(videoVo);
            }
        }

        pageBeanVo.setItems(videoVoList);

        return pageBeanVo;
    }

    //发布视频
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void saveVideo(Long userId, MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {

        //1. 将图片上传到阿里云
        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());

        //2. 将视频上传到fastDFS
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(),
                FileUtil.extName(videoFile.getOriginalFilename()), null);
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();

        //3. 组装video
        Video video = new Video();
        video.setId(ObjectId.get());
        video.setCreated(System.currentTimeMillis());
        video.setUserId(userId);
        video.setText("左手右手一个慢动作~~~");
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);

        //4. 执行保存
        videoService.saveVideo(video);

        mqVideoManager.sendVideoMsg(video.getId().toHexString(), MQVideoManager.VIDEO_PUBLISH);
    }

    //关注用户
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void userFocus(Long focusId,Long userId) {
        //1. 组装focus对象
        FocusUser focusUser = new FocusUser();
        focusUser.setCreated(System.currentTimeMillis());
        focusUser.setUserId(UserHolder.get().getId());//登录用户id
        focusUser.setFocusUserId(focusId);//视频发布用户id

        //2. 调用service保存关注
        videoService.saveUserFocus(focusUser);

        //3. 在redis中生成关注标识   99_1   focus_user:{}_{}
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.get().getId(), focusId);
        stringRedisTemplate.opsForValue().set(key, "1");
    }

    //取消关注用户
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void userUnFocus(Long focusId,Long userId) {

        //2. 调用service删除关注
        videoService.deleteUserFocus(UserHolder.get().getId(),focusId);

        //3. 从redis中删除关注标识   99_1   focus_user:{}_{}
        String key = StrUtil.format(ConstantUtil.FOCUS_USER, UserHolder.get().getId(), focusId);
        stringRedisTemplate.delete(key);
    }

    //小视频点赞
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void likeVideo(String videoId,Long userId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//视频id
        comment.setCommentType(4);//点赞
        comment.setUserId(UserHolder.get().getId());//操作人id

        //2. 调用service完成点赞
        commentService.likeVideo(comment);

        //3. 向redis中记录点赞操作
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), videoId), "1");

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_LIKE);
    }

    //小视频取消点赞
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void dislikeVideo(String videoId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//视频id
        comment.setCommentType(4);//点赞
        comment.setUserId(UserHolder.get().getId());//操作人id

        //2. 调用service完成取消点赞
        commentService.dislikeVideo(comment);

        //3. 向redis中删除点赞操作
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), videoId));

        mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_DISLIKE);
    }

    //保存视频评论
    @CacheEvict(value = "tanhua", key = "'video_'+#userId+':*'")
    public void saveVideoComment(String videoId, String textComment,Long userId) {
        //1. 组装comment对象
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(videoId));//动态id
        comment.setCommentType(5);//评论
        comment.setUserId(UserHolder.get().getId());//操作人
        comment.setContent(textComment);//评论内容

        comment.setIsParent(true);//设置为父节点
        //判断该用户是否是封冻用户
        UserInfo userInfo = userInfoService.findById(userId);
        UserFreezing userFreezing = freezingService.findFreezing(userId, userInfo.getFreezingRange());
        if (userFreezing != null && userInfo.getUserStatus().equals("2")) {
            if (userFreezing.getFreezingRange() == 2) {
                if (userFreezing.getFreezingTime() == 1 && new Date().getTime() > DateUtil.offsetDay(userFreezing.getFreezing(), 3).getTime()) {
                    //2. 调用service保存评论
                    commentService.saveVideoComment(comment);
                    userInfo.setUserStatus(1 + "");
                    userInfoService.update(userInfo);

                } else if (userFreezing.getFreezingTime() == 2 && new Date().getTime() > DateUtil.offsetDay(userFreezing.getFreezing(), 7).getTime()) {
                    //2. 调用service保存评论
                    commentService.saveVideoComment(comment);
                    userInfo.setUserStatus(1 + "");
                    userInfoService.update(userInfo);
                } else if (userFreezing.getFreezingTime() == 3) {
                    System.out.println("不好意思你被封了");
                }
            }
        }else{
            //2. 调用service保存评论
            commentService.saveVideoComment(comment);

            mqVideoManager.sendVideoMsg(videoId, MQVideoManager.VIDEO_COMMENT);
        }

    }



    //视频评论列表
    public PageBeanVo videosCommentsList(String videoId, Integer pageNum, Integer pageSize) {

        //调用service查询评论列表
        PageBeanVo pageBeanVo = videoService.videosCommentsList(videoId, pageNum, pageSize);
        List<Comment> commentList = (List<Comment>) pageBeanVo.getItems();
        List<CommentVo> commentVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(commentList)) {
            for (Comment comment : commentList) {
                Long uid = comment.getUserId();
                UserInfo userInfo = userInfoService.findById(uid);
                CommentVo commentVo = new CommentVo();
                commentVo.setAvatar(userInfo.getAvatar());
                commentVo.setNickname(userInfo.getNickname());
                commentVo.setId(comment.getId().toHexString());
                commentVo.setContent(comment.getContent());
                commentVo.setCreateDate(DateFormatUtil.format(new Date(comment.getCreated())));
                //判断是否已经点赞
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, UserHolder.get().getId(), comment.getId()))) {
                    commentVo.setHasLiked(1);
                }
                commentVo.setLikeCount(comment.getLikeCount());

                commentVoList.add(commentVo);
            }
        }
        pageBeanVo.setItems(commentVoList);
        return pageBeanVo;
    }

    //保存喜欢
    public void videoCommentsLike(String commentId) {
        Long userId = UserHolder.get().getId();
        Comment comment = videoService.findVideoComment(commentId);

        Integer likeCount = videoService.videoCommentsLike(comment,userId);
        System.out.println("喜欢后"+likeCount);
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,commentId),"1");

    }

    //取消喜欢
    public void videoCommentsDislike(String commentId) {
        Long userId = UserHolder.get().getId();
        Comment comment = videoService.findVideoComment(commentId);
        comment.setCommentType(6);

        Integer likeCount = videoService.videoCommentsDislike(comment,userId);
        System.out.println("取消喜欢后"+likeCount);
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE,userId,commentId));
    }
}